#pragma once
#include "Log.hpp"
#include <string>
#include <jsoncpp/json/json.h>
#include <iostream>
#include <sstream>
#include <memory>
using namespace std;
using namespace MyLogModule;

const string Sep = "\r\n";
//添加报头+格式化
//{json} -- > len\r\n{json}\r\n
bool Encode(string& message)
{
    int len = message.size();
    cout << "message length: " << len << endl;
    if(0 == len)
        return false;
    string package = to_string(len) + Sep + message + Sep;
    message = package;
    return true;
}

//检查报文的完整性
//len\r\n{json}\r\n
//len\r\n{json}\r\nlen\r\n{json}\r\n
//len\r\n{json}\r\nlen\r\n{
//len\r\n{json}
//len\r\n
bool Decode(string& package,string* content)
{
    //1. 先通过报头，获取有效载荷的长度
    auto pos = package.find(Sep);
    if(string::npos == pos)
        return false;
    string content_length_str = package.substr(0,pos);
    int content_length = stoi(content_length_str);

    //2. 计算报文的整体长度
    int full_length = content_length + content_length_str.size() + 2 * Sep.size();

    //3. 判断报文是否完整
    if(package.size() < full_length)
        return false;
    *content = package.substr(pos + Sep.size(),content_length);

    //4. 从报文中取出一条报文
    package.erase(0,full_length);
    return true;
}

//请求
class Request
{
private:
    int _x;
    int _y;
    char _op;

public:
    Request(int x = 0, int y = 0, char op = 0)
        : _x(x), _y(y), _op(op)
    {
    }
    ~Request()
    {
    }

    bool Serialize(string &out_string)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;
        // 1. 使用toStyledString方法
        //  string ret = root.toStyledString();
        //  cout << ret << endl;

        // 使用工厂模式
        Json::StreamWriterBuilder builder;
        std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
        std::stringstream ss;
        writer->write(root, &ss);
        out_string = ss.str();
        // cout << ss.str() << endl;
        return true;
    }

    bool DeSerialize(string &in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool paseSuccess = reader.parse(in_string, root);
        if (!paseSuccess)
        {
            cout << "Json parse fail" << reader.getFormattedErrorMessages() << endl;
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        return true;
    }

    void Print()
    {
        cout << _x << endl;
        cout << _op << endl;
        cout << _y << endl;
    }

    int GetX() const 
    {
        return _x;
    }
    int GetY() const 
    {
        return _y;
    }
    char GetOp() const
    {
        return _op;
    }
};

//响应
class Response
{
private:
    int _result; // 运算结果
    int _code;   // 错误码
public:
    Response(int result = 0,int code = 0)
        :_result(result)
        ,_code(code)
    {}
    ~Response()
    {
    }

    bool Serialize(string& out_string)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::StreamWriterBuilder builder;
        unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
        stringstream ss;
        writer->write(root,&ss);
        out_string = ss.str();
        return true;
    }

    bool DeSerialize(string& in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool parseSuccess = reader.parse(in_string,root);
        if(!parseSuccess)
        {
            cout << "Json parse fail" << reader.getFormattedErrorMessages();
            return false;
        }

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }

    int GetResult()
    {
        return _result;
    }

    int GetCode()
    {
        return _code;
    }

    void SetResult(int ret)
    {
        _result = ret;
    }

    void SetCode(int code)
    {
        _code = code;
    }
};
